#include <avr/io.h>
#include "enc28j60.h"
#include "netstack.h"
//#include <stdio.h>
#include <stdbool.h>
//#include "smartprintf.h"
#include "z:\trunk\terminal.h"


uint8_t myip_addr[4] = {192,168,1,96};

void set_mac(uint8_t*, uint8_t*, uint8_t*);
void set_ip(uint8_t*, uint8_t*, uint8_t*);
bool check_mac(uint8_t*);
bool check_ip(uint8_t*);
void arp_handle(struct ETH_header*, uint16_t);
void arp_response(struct ETH_header*, struct ARP_header*, uint16_t);
void ip_handle(struct ETH_header*, uint16_t);
void icmp_handle(struct ETH_header*, struct IP_header*, uint16_t);
void icmp_replay(struct ETH_header*, struct IP_header*, struct ICMP_header*, uint16_t);
uint16_t checksum(uint8_t*, uint8_t);
void udp_handle(struct ETH_header*, struct IP_header*, struct UDP_header*, uint16_t);
void tcp_handle(struct ETH_header* eth, struct IP_header* ip, struct TCP_header* tcp, uint16_t len);
uint16_t bint_to_lint(uint16_t);
uint16_t lint_to_bint(uint16_t);
void arp_request(uint8_t*);
void udp_send(uint8_t*, uint8_t*, uint8_t*, uint16_t, uint16_t);
bool check_broad(uint8_t* mac_addr);
void calc_seqnum(struct TCP_header* tcp, uint16_t datalen);
void tcp_servicehandle(struct ETH_header* eth, struct IP_header* ip, struct TCP_header* tcp, uint16_t len);
uint8_t tcp_conhandle(struct ETH_header* eth, struct IP_header* ip, struct TCP_header* tcp, uint16_t len);
void prep_tcp_packet(struct ETH_header* eth, struct IP_header* ip, struct TCP_header* tcp, uint16_t len, uint16_t datalen);
void tcp_send(uint8_t* data, uint8_t* mac_addr, uint8_t* ip_addr, uint16_t srcport, uint16_t destport);

#define MAX_SOCKETS 3;
//struct TCP_socket sockets[MAX_SOCKETS] = {{false, 0, 0, 0, 0, 0},
//								{false, 0, 0, 0, 0, 1},
//								{false, 0, 0, 0, 0, 2}};
//uint8_t socketidx = 0;

#define ARP_CACHE_SIZE 2
uint8_t arp_cache_idx = 0;	
arp_alloc arp_cache[1];
//uint8_t arp_request = false;
uint8_t count = 0;
struct TCP_socket socket;

void net_init(void)
{
	enc_init();
	pstring("init\n\r");
}

void net_handle(void)
{
/*
	if(count == 0)
	{
		uint8_t ipad[4] = { 192, 168, 1, 11};
		uint8_t mac[6] = { 0x4E, 0x80, 0x98, 0x9B, 0xDE, 0xF0 };
		uint8_t data[] = "\n\rHELLO WORLD\n\r";
		udp_send(data, mac, ipad, 50, 4000);
	//	arp_request(ipad);
		count = 1;
	}
*/	



	uint16_t len = enc_readpacket(BUFFER_SIZE, buffer);

	if(len)
	{
		struct ETH_header *eth;
		eth = (struct ETH_header*)&buffer[0];

		//broadcast 
		if(eth->ETH_destmac[0] == 0xff && eth->ETH_destmac[1] == 0xff && eth->ETH_destmac[2] == 0xff &&
			eth->ETH_destmac[3] == 0xff && eth->ETH_destmac[4] == 0xff && eth->ETH_destmac[5] == 0xff)
		{
			if(TYPE_ARP == eth->ETH_type)
			{	
				arp_handle(eth, len);
			}
		}

		//dest is mymac
		if(check_mac(eth->ETH_destmac))
		{
			if(TYPE_ARP == eth->ETH_type)
			{	
				arp_handle(eth, len);
			}

			if(TYPE_IP == eth->ETH_type)
			{	
				ip_handle(eth, len);
			}
		}
	}
}


void ip_handle(struct ETH_header* eth,uint16_t len)
{
	struct IP_header *ip;
	ip = (struct IP_header*)&buffer[23];

	if(IPTYPE_ICMP == ip->IP_protocol)
	{
		icmp_handle(eth, ip, len);
	}

	if(IPTYPE_UDP == ip->IP_protocol)
	{
		struct UDP_header *udp;
		udp = (struct UDP_header*)&buffer[34];
		udp_handle(eth, ip, udp, len);
	}

	if(IPTYPE_TCP == ip->IP_protocol)
	{
		struct TCP_header *tcp;
		tcp = (struct TCP_header*)&buffer[34];
		tcp_handle(eth, ip, tcp, len);

	}

} 


void tcp_handle(struct ETH_header* eth, struct IP_header* ip, struct TCP_header* tcp, uint16_t len)
{	
	uint16_t tmp = tcp->TCP_srcport;
	tcp->TCP_srcport = tcp->TCP_destport;
	tcp->TCP_destport = tmp;

	if(tcp_conhandle(eth, ip, tcp, len)){}
	else	
	{	
		socket.seq_counter = bint_to_lint(tcp->TCP_seqnumber_p1);
		socket.seq_counter = socket.seq_counter << 16;
		socket.seq_counter |= bint_to_lint(tcp->TCP_seqnumber_p2);

		socket.ack_counter = bint_to_lint(tcp->TCP_acknumber_p1);
		socket.ack_counter = socket.ack_counter << 16;
		socket.ack_counter = bint_to_lint(tcp->TCP_acknumber_p2);

		tcp_servicehandle(eth, ip, tcp, len);
	}
}

uint8_t tcp_conhandle(struct ETH_header* eth, struct IP_header* ip, struct TCP_header* tcp, uint16_t len)
{
	//new connection from client --> SYN = 1, ACK = 0
	if(   ((tcp->TCP_flags >> TCP_SYN) & 1) &&
		 (~(tcp->TCP_flags >> TCP_ACK) & 1) )
	{				

/*
		sockets[socketidx].srcport = bint_to_lint(tcp->TCP_destport);
		sockets[socketidx].destport = bint_to_lint(tcp->TCP_srcport);
		sockets[socketidx].seq_counter = bint_to_lint(tcp->TCP_seqnumber_p1);
		sockets[socketidx].seq_counter = socket.seq_counter << 16;
		sockets[socketidx].seq_counter |= bint_to_lint(tcp->TCP_seqnumber_p2);

		socketidx = sockets[socketidx].next;
		
*/
		
//			if(!sockets[i].state)
/*				sockets[i].state = 1;
				sockets[i].srcport = bint_to_lint(tcp->TCP_destport);
				sockets[i].destport = bint_to_lint(tcp->TCP_srcport);

				sockets[i].seq_counter = bint_to_lint(tcp->TCP_seqnumber_p1);
				sockets[i].seq_counter = socket.seq_counter << 16;
				sockets[i].seq_counter |= bint_to_lint(tcp->TCP_seqnumber_p2);

*/



//		socket.state = 1;
		socket.srcport = bint_to_lint(tcp->TCP_destport);
		socket.destport = bint_to_lint(tcp->TCP_srcport);

		socket.seq_counter = bint_to_lint(tcp->TCP_seqnumber_p1);
		socket.seq_counter = socket.seq_counter << 16;
		socket.seq_counter |= bint_to_lint(tcp->TCP_seqnumber_p2);



		tcp->TCP_flags |= (1 << TCP_ACK);

		calc_seqnum(tcp, 0);

		prep_tcp_packet(eth, ip, tcp, len - 4, 0);
	
		enc_sendpacket(len - 4, buffer);

		socket.state = 1;

		return 1;
	}

/*
	if(   ((tcp->TCP_flags >> TCP_SYN) & 1) &&
		 ((tcp->TCP_flags >> TCP_ACK) & 1) )
	{
		tcp_send(data, mac_addr, ip_addr, srcport, destport)
	}	 	
*/
	
	if((tcp->TCP_flags >> TCP_RST) & 1)
	{
		return 1;
	}

	if((tcp->TCP_flags >> TCP_FIN) & 1)
	{
		tcp->TCP_flags |= (1 << TCP_FIN);

		calc_seqnum(tcp, 0);

		prep_tcp_packet(eth, ip, tcp, len - 4, 0);
	
		enc_sendpacket(len - 4, buffer);

		socket.state = 0;
/*
		socket.srcport = 0;
		socket.destport = 0;
		socket.seq_counter = 0;
		socket.ack_counter = 0;
*/
		return 1;
	}	

	return 0;
}

uint16_t tcp_calcdatalen(struct TCP_header* tcp)
{
		struct IP_defheader* ipdef =(struct IP_defheader*) &buffer[IP_HEADERPOS];
		uint16_t datalen = bint_to_lint(ipdef->IP_len) - IP_HEADERLENGTH - ((tcp->TCP_len >> 4) * 4);	
		return datalen;
}


uint8_t testcount = 1;
void tcp_servicehandle(struct ETH_header* eth, struct IP_header* ip, struct TCP_header* tcp, uint16_t len)
{
	
if(socket.destport == PORT_TELNET)
{

	pstring("\n\rincomming telnet");

	uint16_t datalen = tcp_calcdatalen(tcp);

//	if(tcp_calcdatalen(tcp) > 0)	
	if(datalen > 0)
	{
		tcp->TCP_flags |= (1 << TCP_ACK);
//		uint16_t datalen = tcp_calcdatalen(tcp);

/*
		uint8_t i;
		pstring("\n\r");

			for(i = 0; i < datalen; i++)
			{
				pchar(buffer[TCP_HEADERPOS + ((tcp->TCP_len >> 4) * 4) + i]);
			}		

		pstring("\n\r");
*/
		calc_seqnum(tcp, datalen);
		
		
		// ack packet
		prep_tcp_packet(eth, ip, tcp, len - 4, 0);

		enc_sendpacket(len - 4, buffer);

	}

	

	if(socket.state == 1 && testcount == 1)
	{
		pstring("\n\r send tcp packet");		
		uint8_t test[] = "test\n\r";
		uint8_t ipad[4] = { 192, 168, 1, 11};
		uint8_t mac[6] = { 0x4E, 0x80, 0x98, 0x9B, 0xDE, 0xF0 };
		tcp_send(test, mac, ipad, socket.srcport, socket.destport);
		testcount = 0;
	}

}
	if(socket.destport == PORT_HTTP)
	{
		pstring("\n\r http_handle\n\r");
	}
}

void prep_tcp_packet(struct ETH_header* eth, struct IP_header* ip, struct TCP_header* tcp, uint16_t len, uint16_t tcp_datalen)
{
	set_mac(eth->ETH_destmac, eth->ETH_sourcemac, eth->ETH_sourcemac);

	struct IP_defheader ipdef = IP_DEFHEADER;
	ipdef.IP_len = lint_to_bint(IP_HEADERLENGTH + ((tcp->TCP_len >> 4) * 4) + tcp_datalen);
	*((struct IP_defheader *) &buffer[IP_HEADERPOS]) = ipdef;

	set_ip(ip->IP_destip, ip->IP_sourceip, ip->IP_sourceip );

	ip->IP_protocol = IPTYPE_TCP;
	ip->IP_chksum = 0;
	ip->IP_chksum = checksum(&buffer[IP_HEADERPOS], IP_HEADERLENGTH);

	tcp->TCP_chksum = 0;
	tcp->TCP_window = lint_to_bint(300);

	struct TCP_pheader tcp_pheader;
	set_ip(tcp_pheader.destip, tcp_pheader.srcip, ip->IP_destip);
	tcp_pheader.zero = 0;
	tcp_pheader.protocol = ip->IP_protocol;
	tcp_pheader.tcplen = lint_to_bint((tcp->TCP_len >> 4) * 4);

	tcp->TCP_acknumber_p1 = lint_to_bint(socket.seq_counter >> 16); 
	tcp->TCP_acknumber_p2 = lint_to_bint(socket.seq_counter & 0xFFFF);
	tcp->TCP_seqnumber_p1 = lint_to_bint(socket.ack_counter >> 16);
	tcp->TCP_seqnumber_p2 = lint_to_bint(socket.ack_counter & 0xFFFF);

	tcp->TCP_chksum = checksum(&buffer[TCP_HEADERPOS],((tcp->TCP_len >> 4) * 4) + tcp_datalen) +
		checksum((uint8_t*)&tcp_pheader, 12);


	int z;
	uint8_t* header = (uint8_t*)&tcp_pheader;
	pstring("\n\r prep packet: ");
	phex(checksum((uint8_t*)&tcp_pheader, 12));
	pstring("\n\r");
	for(z = 0; z< 12; z++)
	{
		pstring("\n\r");
		phex(header[z]);
	}
}


void calc_seqnum(struct TCP_header* tcp, uint16_t tcp_datalen)

{

	if(	(((tcp->TCP_flags >> TCP_SYN) & 1) ||
		((tcp->TCP_flags >> TCP_FIN) & 1))  
			&& tcp_datalen == 0)
    {
    	tcp_datalen = 1;
    }
    
	socket.seq_counter = socket.seq_counter + tcp_datalen;
}

void tcp_connect(uint16_t destport)
{
}

void tcp_send(uint8_t* data, uint8_t* mac_addr, uint8_t* ip_addr, uint16_t srcport, uint16_t destport)
{
	struct ETH_header *eth;
	eth = (struct ETH_header*)&buffer[0];

	struct IP_header *ip;
	ip = (struct IP_header*)&buffer[23];

	struct TCP_header *tcp;
	tcp = (struct TCP_header*)&buffer[34];

	set_mac(eth->ETH_destmac, eth->ETH_sourcemac, mac_addr);
	eth->ETH_type = TYPE_IP;

	uint8_t i = 0;


	while(data[i] != '\0')
	{
		buffer[i + TCP_HEADERPOS + TCP_HEADERLENGTH] = data[i];
		i++;		
	}


	struct IP_defheader ipdef = IP_DEFHEADER;
	ipdef.IP_len = lint_to_bint(IP_HEADERLENGTH + TCP_HEADERLENGTH + i);
	*((struct IP_defheader *) &buffer[IP_HEADERPOS]) = ipdef;

	set_ip(ip->IP_destip, ip->IP_sourceip, ip_addr );
	
	ip->IP_protocol = IPTYPE_TCP;
	ip->IP_chksum = 0;
	ip->IP_chksum = checksum(&buffer[IP_HEADERPOS], IP_HEADERLENGTH);

	tcp->TCP_destport = lint_to_bint(srcport);
	tcp->TCP_srcport = lint_to_bint(destport);
//	tcp->TCP_flags = 0;

	tcp->TCP_chksum = 0;

	tcp->TCP_len = ((TCP_HEADERLENGTH / 4) << 4);
	
	struct TCP_pheader tcp_pheader;
	set_ip(tcp_pheader.destip, tcp_pheader.srcip, ip->IP_destip);
	tcp_pheader.zero = 0;
	tcp_pheader.protocol = ip->IP_protocol;
//	tcp_pheader.tcplen = tcp->TCP_len;

	tcp_pheader.tcplen = lint_to_bint(TCP_HEADERLENGTH);

tcp->TCP_flags |= (1 << TCP_ACK);

//	tcp->TCP_chksum = checksum(&buffer[TCP_HEADERPOS],((tcp->TCP_len >> 4) * 4) + tcp_datalen) +
//		checksum((uint8_t*)&tcp_pheader, 12);
	
//	prep_tcp_packet(eth, ip, tcp, 60, TCP_HEADERLENGTH + i);

	tcp->TCP_acknumber_p1 = lint_to_bint(socket.seq_counter >> 16); 
	tcp->TCP_acknumber_p2 = lint_to_bint(socket.seq_counter & 0xFFFF);
	tcp->TCP_seqnumber_p1 = lint_to_bint(socket.ack_counter >> 16);
	tcp->TCP_seqnumber_p2 = lint_to_bint(socket.ack_counter & 0xFFFF);

	tcp->TCP_chksum = checksum(&buffer[TCP_HEADERPOS],TCP_HEADERLENGTH + i) +
		checksum((uint8_t*)&tcp_pheader, 12);

	pstring("\n\r sendlen: ");
	pdigit(TCP_HEADERLENGTH + i);
	pstring("\n\r phchecksum: ");
	phex(checksum((uint8_t*)&tcp_pheader,12));
	pstring("\n\r");
	
/*
	int z;
	uint8_t* buffer = (uint8_t*)&buffer;
	for(z = 0; z< (TCP_HEADERLENGTH + i); z++)
	{
		pstring("\n\r");
		phex(buffer[z]);
	}
*/
	enc_sendpacket(80, buffer);

}


void udp_handle(struct ETH_header* eth, struct IP_header* ip, struct UDP_header* udp, uint16_t len)
{
//	smartprintf("\n\r is udp");

//	uint16_t udp_len = (bint_to_lint(udp->UDP_len)) + UDP_DATAPOS - UDP_HEADERLENGTH;
//	uint8_t i;

//	smartprintf("\r\nMessage: ");
//	for(i = UDP_DATAPOS; i < udp_len; i++)
//	{
//		smartprintf("%c", buffer[i]);
//	}
//	smartprintf("\r");
}


void udp_send(uint8_t* data, uint8_t* mac_addr, uint8_t* ip_addr, uint16_t srcport, uint16_t destport)
{
	struct ETH_header *eth;
	eth = (struct ETH_header*)&buffer[0];

	struct IP_header *ip;
	ip = (struct IP_header*)&buffer[23];

	struct UDP_header *udp;
	udp = (struct UDP_header*)&buffer[34];

	set_mac(eth->ETH_destmac, eth->ETH_sourcemac, mac_addr);
	eth->ETH_type = TYPE_IP;

	uint8_t i = 0;

	while(data[i] != '\0')
	{
		buffer[i + UDP_DATAPOS] = data[i];
		i++;		
	}

	struct IP_defheader ipdef = IP_DEFHEADER;
	ipdef.IP_len = lint_to_bint(IP_HEADERLENGTH + UDP_HEADERLENGTH + i);

	*((struct IP_defheader *) &buffer[IP_HEADERPOS]) = ipdef;

	set_ip(ip->IP_destip, ip->IP_sourceip, ip_addr );

	
	ip->IP_protocol = IPTYPE_UDP;
	ip->IP_chksum = 0;
	ip->IP_chksum = checksum(&buffer[IP_HEADERPOS], IP_HEADERLENGTH);
	

	udp->UDP_destport = lint_to_bint(destport);
	udp->UDP_srcport = lint_to_bint(srcport);

	udp->UDP_chksum = 0;
	udp->UDP_len = lint_to_bint(UDP_HEADERLENGTH + i);
	
	struct UDP_pheader udp_phead; //= { myip_addr, ip_addr, IPTYPE_UDP, udp->UDP_len }; 
	
	/*  UDP Pseudo Header for checksum calc
		IP Source Address 4 bytes
		IP Destination Address 4 bytes
		Protocol 2 bytes
		UDP Length 2 bytes */

	set_ip(udp_phead.destip, udp_phead.srcip, ip_addr);
	udp_phead.pad = 0;
	udp_phead.protocol = IPTYPE_UDP;	
	udp_phead.udp_dlen = udp->UDP_len;

	uint8_t* pseudo_header = (uint8_t*)&udp_phead;
	uint16_t chksum_pheader = checksum(pseudo_header, 12);
	uint16_t chksum_udphead = checksum(&buffer[UDP_HEADERPOS], (UDP_HEADERLENGTH + i));
	uint16_t udp_chksum = chksum_pheader + chksum_udphead;

	udp->UDP_chksum = udp_chksum;

/*	if((i + UDP_DATAPOS) < 60)
	{
		for(; (i + UDP_DATAPOS) < 60; i++)
		{
			buffer[i] = 0;
		}
	}
*/	
	enc_sendpacket(60, buffer);
}

uint16_t bint_to_lint(uint16_t bint)
{
	uint16_t lint;
	lint = (bint >> 8) | (bint << 8);
	return lint;
}

uint16_t lint_to_bint(uint16_t lint)
{
	uint16_t bint;
	bint = (lint >> 8) | (lint << 8);
	return bint;
}

void icmp_handle(struct ETH_header* eth, struct IP_header* ip, uint16_t len)
{
	struct ICMP_header *icmp;
	icmp = (struct ICMP_header*)&buffer[34];

	if(ICMP_REQUEST == icmp->ICMP_type)
	{
		icmp_replay(eth, ip, icmp, len);
	}
}

void icmp_replay(struct ETH_header* eth, struct IP_header* ip, struct ICMP_header* icmp, uint16_t len)
{
	set_mac(eth->ETH_destmac, eth->ETH_sourcemac, eth->ETH_sourcemac);
	set_ip(ip->IP_destip, ip->IP_sourceip, ip->IP_sourceip );
	ip->IP_chksum = 0;

	icmp->ICMP_type = ICMP_REPLAY;
	icmp->ICMP_code = 0;

	ip->IP_chksum = checksum(&buffer[IP_HEADERPOS], IP_HEADERLENGTH);
	enc_sendpacket(len - 4, buffer);
}

uint16_t checksum(uint8_t* pointer, uint8_t len)
{	
	/*	1. set checksum field = 0
		2. interprete 2byte as 16bit value (big endian)
		3. add these values
		4. interprete sum bytes as 32bit values and add 
		5. calc ones compliment
	*/


	uint8_t i = 0;
	uint16_t word = 0;
	uint32_t sum = 0;

	while (i < len)
	{
		word = ((pointer[i] << 8) + pointer[i+1]);
		sum += word;		
		i = i + 2;
	}
	
	sum = ((sum >> 16) + (sum & 0x0000FFFF));
	word = ((sum << 8) | (sum >> 8));
	word = ~word;
	return word;
}

void arp_handle(struct ETH_header* eth, uint16_t len)
{
		struct ARP_header *arp;
		arp = (struct ARP_header*)&buffer[21]; 

		if(check_ip(arp->ARP_destip))
		{	
			if(ARP_REQUEST == arp->ARP_opcode)
			{
				arp_response(eth, arp, len);
			}

			if(ARP_RESPONSE == arp->ARP_opcode)
			{
				uint8_t i;
				for(i = 0; i < 6; i++)
				{
					arp_cache[arp_cache_idx].mac_addr[i] = arp->ARP_sourcemac[i]; 
				}

				for(i = 0; i < 4; i++)
				{
					arp_cache[arp_cache_idx].ip_addr[i] = arp->ARP_sourceip[i];
				}
			}
		}
}

bool check_mac(uint8_t* mac_addr)
{	
	if(mac_addr[0] == mymac_addr[0] && mac_addr[1] == mymac_addr[1] && mac_addr[2] == mymac_addr[2] && 
		mac_addr[3] == mymac_addr[3] && mac_addr[4] == mymac_addr[4] && mac_addr[5] == mymac_addr[5])
	{
		return true;
	}
	return false;
}

bool check_ip(uint8_t* ip_addr)
{
	if(ip_addr[0] == myip_addr[0] && ip_addr[1] == myip_addr[1] && 
		ip_addr[2] == myip_addr[2] && ip_addr[3] == myip_addr[3])
	{
		return true;
	}
	return false;
}

void set_mac(uint8_t* packet_dest, uint8_t* packet_src, uint8_t* dest)
{
	uint8_t i;
	for(i = 0; i < 6; i++)
	{
		packet_dest[i] = dest[i];
		packet_src[i] = mymac_addr[i];
	}
}

void set_ip(uint8_t* packet_dest, uint8_t* packet_src, uint8_t* dest)
{
	uint8_t i;
	for(i = 0; i < 4; i++)
	{
		packet_dest[i] = dest[i];
		packet_src[i] = myip_addr[i];
	}
}	
	

void arp_response(struct ETH_header* eth, struct ARP_header* arp, uint16_t len)
{
	set_mac(eth->ETH_destmac, eth->ETH_sourcemac, eth->ETH_sourcemac);
	set_mac(arp->ARP_destmac, arp->ARP_sourcemac, arp->ARP_sourcemac); 	
	set_ip(arp->ARP_destip, arp->ARP_sourceip, arp->ARP_sourceip);
	arp->ARP_opcode = ARP_RESPONSE;


	// -4 enc statusbytes
	enc_sendpacket(len - 4, buffer);

}

void arp_request(uint8_t* ip_addr)
{
	struct ETH_header *eth;
	eth = (struct ETH_header*)&buffer[0];
	
	struct ARP_header *arp;
	arp = (struct ARP_header*)&buffer[21]; 
	
	// eth header: destmac = broadcast, srcmac = mymac, type  = arp
	uint8_t destmac[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
	set_mac(eth->ETH_destmac, eth->ETH_sourcemac, destmac);
	eth->ETH_type = TYPE_ARP;

	
	struct ARP_defheader arpdef = ARP_DEFHEADER;
	*((struct ARP_defheader *) &buffer[ARP_HEADERPOS]) = arpdef;


	arp->ARP_opcode = ARP_REQUEST;
	uint8_t arp_destmac[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
	set_mac(arp->ARP_destmac, arp->ARP_sourcemac, arp_destmac);
	set_ip(arp->ARP_destip, arp->ARP_sourceip, ip_addr);

	uint8_t i;
	//fill min length with null
	for( i = 42; i < 60; i++)
	{
		buffer[i] = 0;
	}

	enc_sendpacket(i, buffer);	
}



